package com.mzz.creational.singleton;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * （6） 枚举类进行暴露，违反了“职责单一原则”（只需要暴露连接信息即可），下面进行完善。
 *
 * @author xushijian
 * @describe 枚举enum和静态代码块的特性相似，在使用枚举类时，构造方法会被自动调用，
 * 也可以应用其这个特性实现单例设计模式，最经典的就是数据库连接。
 */
public enum SingletonEnum6 {

    INSTANCE;

    private Connection connection;

    /**
     * 在使用枚举时，构造方法自动调用
     */
    SingletonEnum6() {

        //初始化获取连接参数信息
        try {
            System.out.print("调用了Singleton的构造！");
            String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false";
            String username = "root";
            String password = "123456";
            String driverName = "com.mysql.cj.jdbc.Driver";
            Class.forName(driverName);
            connection = DriverManager.getConnection(url, username, password);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public Connection getConnection() {
        return connection;
    }

    /**
     * 扩展知识：
     *  职责单一原则：内聚性：一个模块的组成元素之间的功能相关性
     将内聚性和引起一个模块或者类的作用力相联系
     就一个类而言，应该仅有一个引起它变化的原因，职责即变化的原因
     *
     *  开放封闭原则：对扩展开放，对修改封闭
     *
     里氏替换原则：引用基类的地方必须可以使用其子类的对象代替

     依赖倒置原则：模块依赖接口，细节依赖抽象

     接口隔离原则：多个专门接口，而不是一个总接口
     * 举例1
     违背单一职责的接口
     interface Modem
     {
     public void dial(String pon);
     public void hangup();
     public void send(char c);
     public void recv();
     }
     此时的接口有两个职责：

     链接管理：dial(), hangup();
     数据通信：send(), recv();   ---> 类比数据库连接类

     是否应该被分开： 变化的轴线仅当实际发生时才有意义，否则就会有不必要的复杂性。

     应用程序的变化方式总是导致这两个职责同时变化，那么就不必分离；
     反之，这两个职责应该被分离。
     *
     *
     */
}
